uniform extern float4x4 gVP;
uniform extern texture  gTex;
uniform extern float3   gEyePosW;
uniform extern float    gAccel;
uniform extern float    gPSystemTime;
uniform extern int      gViewportHeight;

sampler Tex = sampler_state
{
	Texture = <gTex>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = CLAMP;
    AddressV  = CLAMP;
};

struct VSInput
{
    float3 iniPosW    : POSITION0;
	float3 iniVel     : TEXCOORD0;
	float iniSize     : TEXCOORD1;
	float iniTime     : TEXCOORD2;
	float maxLifeTime : TEXCOORD3;
	float4 color      : COLOR;
};

struct VSOutput
{
    float4 posH : POSITION0;
	float2 tex  : TEXCOORD0;
	float4 color: COLOR0;
	float size  : PSIZE;
};

VSOutput ExplosionVS(VSInput input)
{
	VSOutput output = (VSOutput)0;
	
	float t = gPSystemTime - input.iniTime;
	
	float3 posW = input.iniPosW + input.iniVel * t * (1 + 0.5f * gAccel * t);
	output.posH = mul(float4(posW, 1.0f), gVP);
		
	float d = distance(posW, gEyePosW);
	output.size = gViewportHeight*input.iniSize/(1.0f + 1.0f*d);
	
	output.color = (1.0f - t/input.maxLifeTime) * input.color;

    return output;
}

float4 ExplosionPS(VSOutput input) : COLOR0
{
    return input.color*tex2D(Tex, input.tex);
}

technique AdditiveBlendingSystem
{
    pass P0
    {
        PointSpriteEnable = true;
        AlphaBlendEnable = true;
        SrcBlend = One;
        DestBlend = One;
		ZWriteEnable = false;

        VertexShader = compile vs_1_1 ExplosionVS();
        PixelShader = compile ps_1_1 ExplosionPS();
    }
}

technique ReplaceBlendingSystem
{
    pass P0
    {
        PointSpriteEnable = true;
        AlphaBlendEnable = true;
        SrcBlend = SrcAlpha;
        DestBlend = InvSrcAlpha;
		ZWriteEnable = false;

        VertexShader = compile vs_1_1 ExplosionVS();
        PixelShader = compile ps_1_1 ExplosionPS();
    }
}
